package com.hy.service;

import com.hy.mapper.MedicineOrderMapper;
import com.hy.mapper.OrderItemMapper;
import com.hy.medicine.MedicineOrder;
import com.hy.medicine.OrderItem;
import com.hy.medicine.dingdan.dto.OrderCreateDTO;
import com.hy.medicine.dingdan.dto.OrderItemDTO;
import com.hy.until.SnowflakeIdGenerator;
import com.hy.wxConfig.MyWxPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 * 处理订单相关的所有业务逻辑，包括创建订单、查询订单、支付处理等
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    /**
     * 订单数据访问接口
     */
    @Autowired
    private MedicineOrderMapper orderMapper;

    /**
     * 订单项数据访问接口
     */
    @Autowired
    private OrderItemMapper orderItemMapper;

    /**
     * 药品服务接口
     */
    @Autowired
    private MedicineService medicineService;

    /**
     * 雪花ID生成器
     */
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    /**
     * 微信支付工具类
     */
    @Autowired
    private MyWxPayUtil wxPayUtil;

    /**
     * 创建订单
     * 完整的订单创建流程，包括：
     * 1. 生成订单ID
     * 2. 检查商品库存
     * 3. 创建订单主体
     * 4. 创建订单项
     * 5. 扣减库存
     *
     * @param orderCreateDTO 订单创建数据传输对象
     * @return 创建成功返回订单ID，库存不足返回null
     * @throws RuntimeException 创建过程中出现异常
     */
    @Override
    @Transactional
    public Long createOrder(OrderCreateDTO orderCreateDTO) {
        try {
            // 使用雪花算法生成唯一订单ID
            Long orderId = snowflakeIdGenerator.nextId();
            log.info("开始创建订单，订单ID: {}", orderId);

            // 检查所有商品的库存
            for (OrderItemDTO item : orderCreateDTO.getOrderItems()) {
                if (!medicineService.checkStock(item.getMedicineId().intValue(), item.getQuantity())) {
                    log.warn("商品{}库存不足", item.getMedicineId());
                    return null;
                }
            }

            // 创建订单主体
            MedicineOrder order = new MedicineOrder();
            order.setOrderId(orderId);
            order.setUserId(orderCreateDTO.getUserId().intValue());
            order.setReceiverName(orderCreateDTO.getReceiverName());
            order.setReceiverPhone(orderCreateDTO.getReceiverPhone());
            order.setReceiverAddress(orderCreateDTO.getReceiverAddress());
            order.setPaymentType(orderCreateDTO.getPaymentType());
            order.setPaymentName(orderCreateDTO.getPaymentName());
            order.setDeliveryFee(orderCreateDTO.getDeliveryFee());
            order.setTotalAmount(orderCreateDTO.getTotalAmount());
            order.setActualPayment(orderCreateDTO.getActualPayment());
            order.setOrderStatus(0); // 初始状态：待支付
            order.setCreateTime(new Date());

            // 保存订单主体
            orderMapper.insert(order);
            log.info("订单主体创建成功");

            // 创建订单项列表
            List<OrderItem> orderItems = new ArrayList<>();
            for (OrderItemDTO itemDTO : orderCreateDTO.getOrderItems()) {
                OrderItem item = new OrderItem();
                item.setOrderId(orderId);
                item.setMedicineId(itemDTO.getMedicineId());
                item.setMedicineName(itemDTO.getMedicineName());
                item.setImageUrl(itemDTO.getImageUrl());
                item.setSpecification(itemDTO.getSpecification());
                item.setDosageForm(itemDTO.getDosageForm());
                item.setPrice(itemDTO.getPrice());
                item.setQuantity(itemDTO.getQuantity());
                // 计算商品总价
                item.setTotalPrice(itemDTO.getPrice().multiply(new BigDecimal(itemDTO.getQuantity())));

                orderItems.add(item);
                // 扣减库存
                medicineService.decreaseStock(itemDTO.getMedicineId().intValue(), itemDTO.getQuantity());
            }

            // 批量保存订单项
            orderItemMapper.batchInsert(orderItems);
            log.info("订单项创建成功，共{}个商品", orderItems.size());

            return orderId;
        } catch (Exception e) {
            log.error("创建订单失败", e);
            throw new RuntimeException("创建订单失败: " + e.getMessage());
        }
    }

    /**
     * 获取订单详情
     * 包括订单主体信息和订单项信息
     *
     * @param orderId 订单ID
     * @return 订单详情，不存在返回null
     */
    @Override
    public MedicineOrder getOrderById(Long orderId) {
        MedicineOrder order = orderMapper.selectById(orderId);
        if (order != null) {
            List<OrderItem> items = orderItemMapper.selectByOrderId(orderId);
            order.setOrderItems(items);
            log.info("获取订单详情成功，订单ID: {}", orderId);
        } else {
            log.warn("订单不存在，订单ID: {}", orderId);
        }
        return order;
    }

    /**
     * 获取订单项列表
     *
     * @param orderId 订单ID
     * @return 订单项列表
     */
    @Override
    public List<OrderItem> getOrderItems(Long orderId) {
        return orderItemMapper.selectByOrderId(orderId);
    }

    /**
     * 取消订单
     * 只有待支付状态的订单可以取消
     *
     * @param orderId 订单ID
     * @param userId 用户ID
     * @return 取消成功返回true
     */
    @Override
    @Transactional
    public boolean cancelOrder(Long orderId, Long userId) {
        MedicineOrder order = orderMapper.selectById(orderId);
        if (order == null) {
            log.warn("订单不存在，无法取消，订单ID: {}", orderId);
            return false;
        }
        if (!order.getUserId().equals(userId.intValue())) {
            log.warn("用户无权取消此订单，订单ID: {}, 用户ID: {}", orderId, userId);
            return false;
        }
        if (order.getOrderStatus() != 0) {
            log.warn("订单状态不允许取消，订单ID: {}, 状态: {}", orderId, order.getOrderStatus());
            return false;
        }
        return updateOrderStatus(orderId, 4);
    }

    /**
     * 更新订单状态
     *
     * @param orderId 订单ID
     * @param status 新状态
     * @return 更新成功返回true
     */
    @Override
    public boolean updateOrderStatus(Long orderId, Integer status) {
        boolean result = orderMapper.updateStatus(orderId, status) > 0;
        if (result) {
            log.info("订单状态更新成功，订单ID: {}, 新状态: {}", orderId, status);
        } else {
            log.warn("订单状态更新失败，订单ID: {}, 状态: {}", orderId, status);
        }
        return result;
    }

    /**
     * 检查支付状态
     * 查询微信支付接口获取最新支付状态，并更新订单状态
     *
     * @param outTradeNo 商户订单号
     * @return 支付状态
     * @throws Exception 查询失败时抛出异常
     */
    @Override
    public String checkPayStatus(String outTradeNo) throws Exception {
        if (outTradeNo == null || outTradeNo.trim().isEmpty()) {
            throw new Exception("商户订单号不能为空");
        }

        try {
            // 查询订单信息
            MedicineOrder order = orderMapper.selectByOutTradeNo(outTradeNo);
            if (order == null) {
                throw new Exception("订单不存在");
            }

            // 如果订单已支付，直接返回成功状态
            if (order.getOrderStatus() == 1) {
                return "SUCCESS";
            }

            // 调用微信支付查询接口
            String status = wxPayUtil.checkOrder(outTradeNo);
            log.info("订单支付状态查询结果，订单号: {}, 状态: {}", outTradeNo, status);

            // 根据支付状态更新订单
            switch (status) {
                case "SUCCESS":
                    order.setOrderStatus(1); // 已支付
                    break;
                case "CLOSED":
                case "PAYERROR":
                    order.setOrderStatus(5); // 支付失败
                    break;
                case "REFUND":
                    order.setOrderStatus(6); // 已退款
                    break;
                case "NOTPAY":
                    // 未支付状态不更新订单状态
                    break;
                default:
                    log.warn("未知的支付状态: {}", status);
                    break;
            }

            // 如果订单状态有变化，更新数据库
            if (order.getOrderStatus() != 0) {
                orderMapper.updateById(order);
                log.info("订单状态已更新，订单号: {}, 新状态: {}", outTradeNo, order.getOrderStatus());
            }

            return status;
        } catch (Exception e) {
            log.error("查询支付状态失败，订单号: {}", outTradeNo, e);
            throw new Exception("查询支付状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户订单列表
     * 包含订单项信息，支持按状态筛选
     *
     * @param userId 用户ID
     * @param status 订单状态（可选）
     * @return 订单列表
     */
    @Override
    public List<MedicineOrder> getOrdersWithItemsByUserId(Long userId, Integer status) {
        List<MedicineOrder> orders = orderMapper.selectByUserId(userId, status);
        log.info("查询用户订单列表，用户ID: {}, 状态: {}, 查询到{}条记录", userId, status, orders.size());

        if (!orders.isEmpty()) {
            // 收集所有订单ID
            List<Long> orderIds = orders.stream()
                    .map(MedicineOrder::getOrderId)
                    .collect(Collectors.toList());

            // 批量查询订单项
            List<OrderItem> allItems = orderItemMapper.batchSelectByOrderIds(orderIds);

            // 按订单ID分组
            Map<Long, List<OrderItem>> itemMap = allItems.stream()
                    .collect(Collectors.groupingBy(OrderItem::getOrderId));

            // 设置每个订单的订单项
            orders.forEach(order ->
                    order.setOrderItems(itemMap.getOrDefault(order.getOrderId(), new ArrayList<>()))
            );
        }

        return orders;
    }

    /**
     * 更新订单的商户订单号
     *
     * @param orderId 订单ID
     * @param outTradeNo 商户订单号
     * @return 更新成功返回true
     */
    @Override
    public boolean updateOutTradeNo(Long orderId, String outTradeNo) {
        boolean result = orderMapper.updateOutTradeNo(orderId, outTradeNo) > 0;
        if (result) {
            log.info("更新商户订单号成功，订单ID: {}, 商户订单号: {}", orderId, outTradeNo);
        } else {
            log.warn("更新商户订单号失败，订单ID: {}, 商户订单号: {}", orderId, outTradeNo);
        }
        return result;
    }
}
